﻿using EFCore.BulkExtensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;

namespace PHMEE.EntityFrameworkCore
{
    public class PHMEEEfCoreBulkOperationProvider : IEfCoreBulkOperationProvider, ITransientDependency
    {

        /// <summary>
        /// 批量插入
        /// </summary>
        /// <typeparam name="TDbContext"></typeparam>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="repository"></param>
        /// <param name="entities"></param>
        /// <param name="autoSave"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        async Task IEfCoreBulkOperationProvider.InsertManyAsync<TDbContext, TEntity>(IEfCoreRepository<TEntity> repository, IEnumerable<TEntity> entities, bool autoSave, CancellationToken cancellationToken)
        {
            if (entities == null || entities.Count() == 0)
            {
                return;
            }


            var dbContext = await repository.GetDbContextAsync();

            dbContext.ChangeTracker.Clear();

            await dbContext.BulkInsertAsync(entities, bulkConfig: new BulkConfig { BatchSize = 2000 }, cancellationToken: cancellationToken);

            if (autoSave)
            {
                await dbContext.SaveChangesAsync(cancellationToken);
            }

        }

        /// <summary>
        /// 批量修改
        /// </summary>
        /// <typeparam name="TDbContext"></typeparam>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="repository"></param>
        /// <param name="entities"></param>
        /// <param name="autoSave"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        async Task IEfCoreBulkOperationProvider.UpdateManyAsync<TDbContext, TEntity>(IEfCoreRepository<TEntity> repository, IEnumerable<TEntity> entities, bool autoSave, CancellationToken cancellationToken)
        {
            if (entities == null || entities.Count() == 0)
            {
                return;
            }

            var dbContext = await repository.GetDbContextAsync();

            await dbContext.BulkUpdateAsync(entities, bulkConfig: new BulkConfig { BatchSize = 2000 }, cancellationToken: cancellationToken);

            if (autoSave)
            {
                await dbContext.SaveChangesAsync(cancellationToken);
            }
        }

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <typeparam name="TDbContext"></typeparam>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="repository"></param>
        /// <param name="entities"></param>
        /// <param name="autoSave"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        async Task IEfCoreBulkOperationProvider.DeleteManyAsync<TDbContext, TEntity>(IEfCoreRepository<TEntity> repository, IEnumerable<TEntity> entities, bool autoSave, CancellationToken cancellationToken)
        {
            if (entities == null || entities.Count() == 0)
            {
                return;
            }

            var dbContext = await repository.GetDbContextAsync();

            await dbContext.BulkDeleteAsync(entities, bulkConfig: new BulkConfig { BatchSize = 2000 }, cancellationToken: cancellationToken);

            if (autoSave)
            {
                await dbContext.SaveChangesAsync(cancellationToken);
            }
        }
    }
}
